package cn.modfun.common.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 树对象工具类
 */
public class TreeUtil {

    /**
     * 列表转树对象
     * @param idKey     编号关键字
     * @param pidKey    父编号关键字
     * @param childKey  子节点关键字
     * @param leafKey   叶子节点标识关键字
     * @param rootNode  根节点对象
     * @param allList   所有列表对象
     *
     * @example
     * <p>
     * List<Map < String , Object>> tree = new ArrayList<Map<String,Object>>();
     * Map<String,Object> rootNode = new HashMap<String,Object>();
     * rootNode.put("resource_id", 0l);
     * rootNode.put("resource_pid",-1l);
     * rootNode.put("resource_name", "ROOT");
     * rootNode.put("expand",true);
     * rootNode.put("leaf",true);
     * tree.add(rootNode);
     * tree.addAll(resources);
     * TreeUtil.listToTree("resource_id", "resource_pid", "children","leaf", rootNode, tree);
     * tree.clear();
     * tree.add(rootNode);
     * </p>
     */
    public static void listToTree(String idKey, String pidKey, String childKey, String leafKey, Map<String,Object> rootNode, List<Map<String,Object>> allList){
        allList.remove(rootNode);// 删除掉本身。
        List<Map<String,Object>> tempList = new ArrayList<Map<String,Object>>();// 除去已被用过栏目的集合
        tempList.addAll(allList);
        List<Map<String,Object>> children = new ArrayList<Map<String,Object>>();// 本级子栏目
        for (Map<String,Object> node : allList) {
            if (rootNode.get(idKey)!=null && node.get(pidKey) !=null && rootNode.get(idKey).toString().equals(node.get(pidKey).toString())) {
                children.add(node);
                tempList.remove(node);
            }
        }
        rootNode.put(leafKey,true);
        if (children.size() == 0) {
            return;
        } else {
            rootNode.put(childKey, children);
            rootNode.put("leaf",false);
            rootNode.put("expanded",true);
            for (Map<String,Object> temp : children) {
                listToTree(idKey,pidKey,childKey,leafKey,temp, tempList);
            }
        }
    }

    /**
     * 列表转树对象
     * @param idKey     编号关键字
     * @param pidKey    父编号关键字
     * @param childKey  子节点关键字
     * @param rootNode  根节点对象
     * @param allList   所有列表对象
     *
     * @example
     * <p>
     * List<Map < String , Object>> tree = new ArrayList<Map<String,Object>>();
     * Map<String,Object> rootNode = new HashMap<String,Object>();
     * rootNode.put("resource_id", 0l);
     * rootNode.put("resource_pid",-1l);
     * rootNode.put("resource_name", "ROOT");
     * rootNode.put("expand",true);
     * rootNode.put("leaf",true);
     * tree.add(rootNode);
     * tree.addAll(resources);
     * TreeUtil.listToTree("resource_id", "resource_pid", "children", rootNode, tree);
     * tree.clear();
     * tree.add(rootNode);
     * </p>
     */
    public static void listToTree(String idKey,String pidKey,String childKey, Map<String,Object> rootNode, List<Map<String,Object>> allList){
        listToTree(idKey,pidKey,childKey,"leaf",rootNode,allList);
    }

    /**
     * 树转列表递归方法
     * @param node      当前节点
     * @param childKey  子节点关键字
     * @param list      用于存储的对象
     * @param keepKeys  保留的关键字
     */
    public static void _treeToList(Map<String,Object> node,String childKey,List<Map<String,Object>> list,String ... keepKeys){
        Map<String,Object> n = new HashMap<String,Object>();
        for(String k : keepKeys){
            n.put(k,node.get(k)!=null?node.get(k).toString():null);
        }
        list.add(n);
        if(node.get(childKey)!=null){
            List<Map<String,Object>> children = (List<Map<String, Object>>) node.get(childKey);
            for(int i=0;i<children.size();i++){
                _treeToList(children.get(i),childKey,list,keepKeys);
            }
        }
    }

    /**
     * 树转列表
     * @param tree      树对象，需是一个集合对象
     * @param childKey  子节点关键字
     * @param keepKeys  保留的关键字
     * @return
     */
    public static List<Map<String,Object>> treeToList(List<Map<String,Object>> tree,String childKey,String ... keepKeys){
        List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        if(tree!=null){
            for(int i = 0;i<tree.size();i++){
                Map<String,Object> node = tree.get(i);
                _treeToList(node,childKey,list,keepKeys);
            }
        }
        return list;
    }

    /**
     * 树转列表
     * @param rootNode  根节点对象
     * @param childKey  子节点关键字
     * @param keepKeys  保留的关键字
     * @return
     */
    public static List<Map<String,Object>> treeToList(Map<String,Object> rootNode,String childKey,String ... keepKeys){
        List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        if(rootNode!=null){
            _treeToList(rootNode,childKey,list,keepKeys);
        }
        return list;
    }

    /**
     * 树转列表递归方法(依赖 fastjson)
     * @param node      JSONObject(fastjson)当前节点
     * @param childKey  子节点关键字
     * @param list      JSONArray(fastjson)用于存储的对象
     * @param keepKeys  保留的关键字
     */
    public static void _treeToList(JSONObject node, String childKey, JSONArray list, String... keepKeys){
        JSONObject n = new JSONObject();
        for(String k : keepKeys){
            n.put(k, node.getString(k)!=null?node.getString(k):null);
        }
        list.add(n);
        if(node.get(childKey)!=null){
            JSONArray children = node.getJSONArray(childKey);
            for(int i=0;i<children.size();i++){
                _treeToList(children.getJSONObject(i),childKey,list,keepKeys);
            }
        }
    }

    /**
     * 树转列表
     * @param tree      树对象，需是一个集合对象
     * @param childKey  子节点关键字
     * @param keepKeys  保留的关键字
     * @return
     */
    public static JSONArray treeToList(JSONArray tree,String childKey,String ... keepKeys){
        JSONArray list = new JSONArray();
        if(tree!=null){
            for(int i = 0;i<tree.size();i++){
                JSONObject node = tree.getJSONObject(i);
                _treeToList(node,childKey,list,keepKeys);
            }
        }
        return list;
    }

    /**
     * 树转列表
     * @param rootNode  根节点对象
     * @param childKey  子节点关键字
     * @param keepKeys  保留的关键字
     * @return
     */
    public static JSONArray treeToList(JSONObject rootNode,String childKey,String ... keepKeys){
        JSONArray list = new JSONArray();
        if(rootNode!=null){
            _treeToList(rootNode,childKey,list,keepKeys);
        }
        return list;
    }
}
